package benny.ApkposStore.Service;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.serial.SerialPort;
import android.util.Log;
import benny.ApkposStore.db.DBHelper;
import benny.ApkposStore.utils.ApkConfigdbUntils;
import benny.ApkposStore.utils.ApkUntils;

public class DishprintService extends IntentService {

	final private int mSleepTime = 5000; // 10s
	static String tag = "DishprintService";
	private static Context mcx = null;
	private int bill = 0;
	static HashMap<String, String> room_map = null;

	private HashMap<String, String> print_map = null;
	static List<HashMap<String, String>> total_map;
	private static String Default_Host = "192.168.0.222";
	private static String Print_Host = null;
	private static String Total_Host = null;
	// ///////////////////打印指令
	static byte[] print_1BC = { 0x1B, 0x21, 0x18 };// 1倍加大加粗
	static byte[] print_3BCM = { 0x1C, 0x21, 0x0C, 0x1B, 0x21, 0x30, 0x1B,
			0x61, 0x31 };// 3倍加大加粗居中
	static byte[] print_M = { 0x1B, 0x61, 0x31 };// 居中
	static byte[] print_2B = { 0x1D, 0x21, 0x01 };// 2倍加大
	static byte[] print_2BM = { 0x1D, 0x21, 0x01, 0x1B, 0x61, 0x31 };// 2倍加大
	static byte[] print_2BD = { 0x1D, 0x21, 0x10 };// 2倍加大扁型
	static byte[] print_3B = { 0x1C, 0x21, 0x0C, 0x1B, 0x21, 0x30 };// 3倍加大加粗
	static byte[] print_BEGIN = { 0x1B, 0x40 };// 恢复指令
	static byte[] print_CUT = { 0x1D, 0x56, 0x1, 0x0 };// 切刀
	static byte[] print_ENTER = { 0x0D, 0x0A }; // 换行
	private static int PORT = 9100;
	private static int jcint = 0;
	private static int print_mode = 1;
	private static OutputStream os_start = null;
	private static Socket socket = null;

	public DishprintService() {
		super("DishprintService");
	}

	@Override
	protected void onHandleIntent(Intent intent) {

		while (true) {
			synchronized (this) {
				try {
					// Thread.sleep(100);
					if (room_map == null) {
						room_map = ApkConfigdbUntils.getroommap(mcx);
					}
					if (total_map == null) {
						total_map = ApkConfigdbUntils.gettotalprint_map(
								 mcx);
					}
					if (print_map == null) {
						print_map = ApkConfigdbUntils.getprint_ipmap(
								mcx);
					}

					Thread.sleep(mSleepTime);

					bill = checkprintlist(mcx);
					// System.out.println("检测:" + jcint + " bill:" + bill);
					jcint++;
					if (bill > 0) {
						getprintbill(mcx);

					}

				} catch (Exception e) {
					// TODO: handle exception
					Log.e(tag, e.getMessage());
				}
			}
		}
	}

	public static int checkprintlist(Context cx) {


		Cursor cursor = null;
		String sql = "";
		try {
			sql="update apkpos_orders_print set order_state=0 where order_state<>0 and "
					+ "orderid in (select orderid from apkpos_dishs_print where order_state=0 union "
					+ "select orderid from apkpos_subdishs_print where order_state=0 group by orderid) ";
			ApkUntils.execSQL(cx, sql);
		} catch (Exception e) {
			// TODO: handle exception
			Log.e(tag, e.getMessage());
		}

		String sqlstr = "select count(*) as cnt from apkpos_orders_print where order_state=0";
	    SQLiteDatabase db=null;
		try {
		    db = DBHelper.getReadableDatabase(cx);
			cursor = db.rawQuery(sqlstr, null);
		} catch (Exception e) {
			// TODO: handle exception
			Log.e(tag, e.getMessage());
		}

		int cnt = 0;
		while (cursor.moveToNext()) {
			cnt = cursor.getInt(cursor.getColumnIndex("cnt"));
		}
		cursor.close();
        db.close();
        db=null;
		return cnt;
	}

	public static void updateprintlist(Context cx,
			String orderid, String dishid, int subdishid) {

		String sql = null;

		if (subdishid > 0) {
			sql = "update  apkpos_subdishs_print set order_state=1 where  orderid='"
					+ orderid
					+ "' and dish_id='"
					+ dishid
					+ "' and subdish_id=" + subdishid + " ";
		} else {
			sql = "update  apkpos_dishs_print set order_state=1 where  orderid='"
					+ orderid + "' and dish_id='" + dishid + "'  ";
		}

		ApkUntils.execSQL(cx,sql);
	}

	public static void getprintbill(Context cx) {

		Cursor cursor = null;
		String sqlstr = "select * from apkpos_orders_print where order_state=0";
		SQLiteDatabase	db = null;
		try {
			db = DBHelper.getReadableDatabase(cx);
			cursor = db.rawQuery(sqlstr, null);
		} catch (Exception e) {
			// TODO: handle exception
			Log.e(tag, e.getMessage());
			return;
		}

		String orders_id = "";
		String table_name = "";
		String people_num = "";
		String table_id = "";
		String table_flag = "";

		while (cursor.moveToNext()) {
			orders_id = cursor.getString(cursor.getColumnIndex("orderid"));
			people_num = cursor.getString(cursor.getColumnIndex("people_num"));
			table_id = cursor.getString(cursor.getColumnIndex("table_num"));
			table_flag = cursor
					.getString(cursor.getColumnIndex("table_extent"));
			table_name = room_map.get(table_id) + table_flag;
			// System.out.println(orders_id);

			Cursor cursordish = null;
			String sql_dish = "select dish_id,0 as subdish_id,dnam_var,dish_num,dish_price,dish_unit,dish_time,order_mode,dcy_name,cook_content,"
					+ "pdet_var,pdet_var_ip from apkpos_dishs_print where order_state=0 and orderid="
					+ orders_id
					+ " "
					+ " union select dish_id,subdish_id,dnam_var,subdish_num,subdish_price,subdish_unit,dish_time,order_mode,dcy_name,cook_content,"
					+ "pdet_var,pdet_var_ip from apkpos_subdishs_print where order_state=0 and orderid="
					+ orders_id + " order by dish_time,dish_id,subdish_id";

			try {

				cursordish = db.rawQuery(sql_dish, null);
			} catch (Exception e) {
				// TODO: handle exception
				Log.e(tag, e.getMessage());
				return;
			}

			if (cursordish.getCount() > 0) {// 打印总单

				for (Iterator<HashMap<String, String>> iterator = total_map
						.iterator(); iterator.hasNext();) { //循环总单打印机
					HashMap<String, String> printer = (HashMap<String, String>) iterator
							.next();
					Cursor cursorprint = null;
					String print_list = printer.get("print_list");
					String spStr[] = print_list.split(",");
					String liststr = "";
					String Str = "";
					for (int i = 0; i < spStr.length; i++) {
						Str = "'" + spStr[i] + "'";
						if (liststr.equals("")) {
							liststr = Str;
						} else {
							liststr = liststr + "," + Str;
						}
					}

					String sql_print = "select dish_id,0 as subdish_id,dnam_var,dish_num,dish_price,dish_unit,dish_time,order_mode,dcy_name,cook_content,"
							+ "pdet_var,pdet_var_ip,print_list from apkpos_dishs_print where order_state=0 and orderid='"
							+ orders_id
							+ "' and pdet_var in ( "
							+ liststr
							+ " ) "
							+ " union select dish_id,subdish_id,dnam_var,subdish_num,subdish_price,subdish_unit,dish_time,order_mode,dcy_name,cook_content,"
							+ "pdet_var,pdet_var_ip,print_list from apkpos_subdishs_print where order_state=0 and orderid='"
							+ orders_id
							+ "' and pdet_var in ( "
							+ liststr
							+ " ) order by dish_time,dish_id,subdish_id";

					try {

						cursorprint = db.rawQuery(sql_print, null);
					} catch (Exception e) {
						// TODO: handle exception
						Log.e(tag, e.getMessage());
						continue;
					}

					if (cursorprint.getCount() > 0) {
						// /打印总单函数
						String printname = printer.get("name");
						String hasprint_list="'list'";
					
						List<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
						while (cursorprint.moveToNext()) {
							 String has_list="aaaa!";
							 has_list = has_list+cursorprint.getString(cursorprint
									.getColumnIndex("print_list"));

							 if (has_list.indexOf(printname)>0) {
								continue;
							}

							hasprint_list=hasprint_list+",'"+ cursorprint.getString(cursorprint
									.getColumnIndex("dish_id"))+"_"+ cursorprint.getString(cursorprint
											.getColumnIndex("subdish_id"))+"'";
							
							HashMap<String, String> map = new HashMap<String, String>();
							String dishnum = cursorprint.getString(cursorprint
									.getColumnIndex("dish_num"));
							String unit = cursorprint.getString(cursorprint
									.getColumnIndex("dish_unit"));
							String dishname = cursorprint.getString(cursorprint
									.getColumnIndex("dnam_var"));
							String cook_content = cursorprint
									.getString(cursorprint
											.getColumnIndex("cook_content"));
							String order_mode = cursorprint
									.getString(cursorprint
											.getColumnIndex("order_mode"));
							String dcy_name = cursorprint.getString(cursorprint
									.getColumnIndex("dcy_name"));
						
							map.put("dish_num", dishnum);
							map.put("dish_unit", unit);
							map.put("dnam_var", dishname);
							map.put("cook_content", cook_content);
							map.put("dcy_name", dcy_name);
							map.put("order_mode", order_mode);
							list.add(map);
						}
						cursorprint.close();
						if (list.size()<1) {
							//System.out.println(printname+"：已经打印过总单；"+hasprint_list);
							continue;
						
						}
						
						Print_Host = printer.get("ip");
						if (print_mode == 0 || Print_Host.equals("com")) {
							try {
								SerialPort sp_start = null;
								try {
									 sp_start = new SerialPort(new File(
												"/dev/ttyS2"), 9600);// ttyS2
								} catch (Exception e) {
									Log.e(tag, "Port exception: " + e.getMessage());
									continue;
								}
								
								os_start = sp_start.getOutputStream();
								printtotal(os_start, orders_id, table_name,
										people_num, printer.get("total_name"),
										list);

								sp_start.close();

							} catch (Exception e) {
								Log.e(tag, "Port exception: " + e.getMessage());
								continue;
							}

						} else {

							try {
								socket = new Socket(Print_Host, PORT);
							} catch (IOException e) {
								Log.e(tag,
										"Socket exception: " + e.getMessage());
								continue;

							}

							try {
								if (socket.isConnected()) {
									if (!socket.isOutputShutdown()) {

										os_start = socket.getOutputStream();

										printtotal(os_start, orders_id,
												table_name, people_num,
												printer.get("total_name"), list);

									}

								}
								socket.close();
							} catch (IOException e) {
								// TODO Auto-generated catch block
								Log.e(tag,
										"Socket exception: " + e.getMessage());
								continue;
							}

						}
						
						try {
							sqlstr=" update apkpos_dishs_print set print_list=ifnull(print_list,'')||'"+printname+"'||';' where " +
									"orderid='"+ orders_id+ "' and dish_id||'_0' in ("+hasprint_list+") ; ";
							sqlstr=sqlstr+" update apkpos_subdishs_print set print_list=ifnull(print_list,'')||'"+printname+"'||';' where " +
									"orderid='"+ orders_id+ "' and dish_id||'_'+subdish_id in ("+hasprint_list+")  ";

							ApkUntils.execSQL(cx,sqlstr);
						//	System.out.println(sqlstr);
						} catch (Exception e) {
							// TODO: handle exception
							Log.e(tag,
									"update hasprint: " + e.getMessage());
							continue;
						}

					}

				}

			}

			while (cursordish.moveToNext()) {
				Print_Host = cursordish.getString(cursordish
						.getColumnIndex("pdet_var_ip"));
				if (Print_Host == null) {
					Print_Host = Default_Host;
				}
				// Print_Host = Default_Host;
				Log.i(tag, "Print_Host:" + Print_Host);
				String dishnum = ApkUntils.convertFloat(cursordish
						.getString(cursordish.getColumnIndex("dish_num")), 1);
				String dish_price = ApkUntils.convertFloat(
						cursordish.getInt(cursordish
								.getColumnIndex("dish_price")) * 0.01 + "", 1);
				String order_mode = cursordish.getString(cursordish
						.getColumnIndex("order_mode"));
				String dish_id = cursordish.getString(cursordish
						.getColumnIndex("dish_id"));
				int subdish_id = cursordish.getInt(cursordish
						.getColumnIndex("subdish_id"));
				String dcy_name = cursordish.getString(cursordish
						.getColumnIndex("dcy_name"));
				String dishname = cursordish.getString(cursordish
						.getColumnIndex("dnam_var"));
				String unit = cursordish.getString(cursordish
						.getColumnIndex("dish_unit"));
				String time = cursordish.getString(cursordish
						.getColumnIndex("dish_time"));

				int msg_int = -1;
				if (print_mode == 0||Print_Host.equals("com")) {
					try {
						SerialPort sp_start=null;
						try {
							 sp_start = new SerialPort(new File(
									"/dev/ttyS2"), 9600);// ttyS2	
						} catch (Exception e) {
							Log.e(tag, "Port exception: " + e.getMessage());
							continue;
						}
										
						os_start = sp_start.getOutputStream();
						msg_int = printdish(os_start, orders_id, order_mode,
								table_name, dcy_name, people_num, dish_price,
								dishnum, unit, dishname, time); // 打印分单
						sp_start.close();

					} catch (Exception e) {
						Log.e(tag, "Port exception: " + e.getMessage());
						continue;
					}

				} else {

					try {
						socket = new Socket(Print_Host, PORT);
					} catch (IOException e) {
						Log.e(tag, "Socket exception: " + e.getMessage());
						continue;

					}

					try {
						if (socket.isConnected()) {
							if (!socket.isOutputShutdown()) {

								os_start = socket.getOutputStream();

								msg_int = printdish(os_start, orders_id,
										order_mode, table_name, dcy_name,
										people_num, dish_price, dishnum, unit,
										dishname, time);

							}

						}
						socket.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						Log.e(tag, "Socket exception: " + e.getMessage());
						continue;
					}

				}

				if (msg_int == 0) {
					try {
						updateprintlist(cx, orders_id, dish_id, subdish_id);

					} catch (Exception e) {
						// TODO: handle exception
						Log.e(tag, "updateprintlist: " + e.getMessage());
						continue;
					}
				}

				
			}

			cursordish.close();

			try {

				sqlstr="update  apkpos_orders_print set order_state=1 where order_state=0 and orderid='"
						+ orders_id + "' ";
				ApkUntils.execSQL(cx, sqlstr);
			} catch (Exception e) {
				// TODO: handle exception
				Log.e(tag, e.getMessage());
				continue;
			}
		}
		cursor.close();
		db.close();
		db=null;
	}

	// 异步打印任务
	public static class AsyncPrintdish extends AsyncTask<Void, Void, Integer> {
		private int print_mode = 1;
		private int msg_int = 1;
		private String msg = "打印失败，请重新尝试！";
		private Socket socket;
		private String HOST = null;
		private int PORT = 9100;
		private String orderid;
		private String dishid;
		private int subdishid = 0;
		private String order_mode = null;
		private String table_name;
		private String dcy_name;
		private String peoplenum;
		private String price;
		private String dishnum;
		private String unit;
		private String dishname;
		private String time;
		static OutputStream os_start;

		public void setPrint_mode(int mode) {
			print_mode = mode;
		}

		public void setPrint_Host(String host) {
			HOST = host;
		}

		public void setPrint_Port(int port) {
			PORT = port;
		}

		public void setdishid(String str) {
			dishid = str;
		}

		public void setsubdishid(int str) {
			subdishid = str;
		}

		public void setorderid(String str) {
			orderid = str;
		}

		public void setorder_mode(String str) {
			order_mode = str;
		}

		public void settable_name(String str) {
			table_name = str;
		}

		public void setdcy_name(String str) {
			dcy_name = str;
		}

		public void setpeoplenum(String str) {
			peoplenum = str;
		}

		public void setprice(String str) {
			price = str;
		}

		public void setdishnum(String str) {
			dishnum = str;
		}

		public void setunit(String str) {
			unit = str;
		}

		public void setdishname(String str) {
			dishname = str;
		}

		public void settime(String str) {
			time = str;
		}

		@Override
		protected Integer doInBackground(Void... params) {

			try {
				if (print_mode == 0) {
					SerialPort sp_start = new SerialPort(
							new File("/dev/ttyS2"), 19200);// ttyS2
					os_start = sp_start.getOutputStream();
					msg_int = printdish(os_start, orderid, order_mode,
							table_name, dcy_name, peoplenum, price, dishnum,
							unit, dishname, time);
					sp_start.close();
				} else {

					try {
						socket = new Socket(HOST, PORT);
					} catch (IOException e) {
						e.printStackTrace();
						msg = "打印失败!网络异常！";
						Log.e(tag, "Socket exception: " + e.getMessage());
						return -1;
					}

					if (socket.isConnected()) {
						if (!socket.isOutputShutdown()) {
							os_start = socket.getOutputStream();
							msg_int = printdish(os_start, orderid, order_mode,
									table_name, dcy_name, peoplenum, price,
									dishnum, unit, dishname, time);

						}
						socket.close();
					}

					// new Thread(new SocketClient()).start();
				}

				if (msg_int == 0) {
					try {
						updateprintlist( mcx, orderid, dishid,
								subdishid);

					} catch (Exception e) {
						// TODO: handle exception
						e.printStackTrace();
					}
				}

			} catch (Exception e) {
				Log.e(tag, "AsyncPrintbill:" + e.getMessage());
				msg = "打印失败！" + e.getMessage();
			}

			return msg_int;

		}

		// 在doInBackground前执行
		protected void onPreExecute() {
			// TODO: 显示正在登陆的提示

		}

		// 在doInBackground后执行
		protected void onPostExecute(Integer result) {

			if (result == 0) {

				Log.e(tag, "AsyncPrintbill:ok ");

			} else {
				Log.e(tag, "AsyncPrintbill: " + msg);
			}
		}
	}

	public static int printtotal(OutputStream socketStream, String orderid,
			String table_name, String peoplenum, String billname,
			List<HashMap<String, String>> list) {
		try {

			String dcy_name = list.get(0).get("dcy_name");
			String order_mode = list.get(0).get("order_mode");

			printline(socketStream, 0, billname + "(总单)", print_3BCM,
					print_ENTER);
			if (!order_mode.equals("")) {
				printline(socketStream, 0, order_mode, print_2B, print_ENTER);
			}

			printline(socketStream, 1, table_name, print_3B, print_ENTER);
			printline(socketStream, 1, " ", null, print_ENTER);

			SimpleDateFormat dateformat = new SimpleDateFormat(
					"HH:mm:ss");
			String time = dateformat.format(new java.util.Date());
			
			printline(socketStream, 1, time + "   " + dcy_name, print_2B,
					print_ENTER);
			printline(socketStream, 0, "单号:"+orderid + "  共" + peoplenum+"人", print_2B,
					print_ENTER);
			String aaa = "";
			for (int i = 0; i < 45; i++) {
				aaa = aaa + "-";
			}
			printline(socketStream, 1, aaa, null, print_ENTER);

			String dishnum = "";
			String unit = "";
			String dishname = "";
			String cook_content = null;
			for (int i = 0; i < list.size(); i++) {
				dishnum = list.get(i).get("dish_num");
				unit = list.get(i).get("dish_unit");
				dishname = list.get(i).get("dnam_var");
				cook_content = list.get(i).get("cook_content");

				if (cook_content != null) {
					dishname = dishname +  cook_content;
				}

				printline(socketStream, 0,lengthstr(dishname," ",20,1) +dishnum + unit 
						, print_3B, print_ENTER);
			}
			aaa = "";
			for (int i = 0; i < 45; i++) {
				aaa = aaa + "-";
			}
			printline(socketStream, 1, aaa, null, print_ENTER);
			
			printline(socketStream, 0," 总计:" +list.size()+"道菜" 
					, print_2B, print_ENTER);
			
			for (int i = 0; i < 3; i++) {
				printline(socketStream, 0, " ", print_3B, print_ENTER);
			}

			socketStream.write(print_CUT);

		} catch (Exception e) {
			e.printStackTrace();
			return -1;
		}

		return 0;

	}
	
	public static String lengthstr(String str, String flag, int length, int state) {

		try {
			if (state == 1) {
				while (str.getBytes("GB18030").length < length) {
					str = str + flag;
				}
			} else {
				while (str.getBytes("GB18030").length < length) {
					str = flag + str;
				}
			}

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return str;
	}

	public static int printdish(OutputStream socketStream, String orderid,
			String order_mode, String table_name, String dcy_name,
			String peoplenum, String price, String dishnum, String unit,
			String dishname, String time) {
		try {
			String newStr = time
					.substring(time.indexOf(" ") + 1, time.length());
			if (order_mode != null) {
				printline(socketStream, 0, order_mode, print_2BM, print_ENTER);
			}

			printline(socketStream, 1, table_name, print_3B, print_ENTER);
			printline(socketStream, 1, " ", null, print_ENTER);
			printline(socketStream, 1, orderid + " " + peoplenum + "人", null,
					print_ENTER);
			printline(socketStream, 0, dcy_name + "  " + newStr + "  ", null,
					null);
			printline(socketStream, 0, price + "元", print_2B, print_ENTER);
			String aaa = "";
			for (int i = 0; i < 45; i++) {
				aaa = aaa + "-";
			}
			printline(socketStream, 1, aaa, null, print_ENTER);
			printline(socketStream, 0, dishnum + " " + unit + " " + dishname,
					print_3B, print_ENTER);
			for (int i = 0; i < 3; i++) {
				printline(socketStream, 0, " ", print_3B, print_ENTER);
			}

			socketStream.write(print_CUT);

		} catch (Exception e) {
			e.printStackTrace();
			return -1;
		}

		return 0;

	}


	public static void printline(OutputStream out, int flag, String ss,
			byte[] start, byte[] end) {

		try {
			if (flag == 1) {
				out.write(print_BEGIN); // 打恢复指令
			}
			if (start != null) {

				out.write(start); // 打开始字体指令
			}

			byte[] dd = ss.getBytes("gbk");
			out.write(dd);
			if (end != null) {
				out.write(end); // 打结束换行指令
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		System.gc();
		super.onDestroy();
	}

	@Override
	public void onStart(Intent intent, int startId) {
		// TODO Auto-generated method stub
		super.onStart(intent, startId);
		// System.out.println("start");
		mcx = DishprintService.this;
	}

}
